#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#include "msg_queue_peer.h"
#include "shmem.h"
#define IPC_WAIT 0
#define STM32_MSG 2
struct msgvalue {
    long type;
    int key;
    bool status;
};
void *send_message(void *arg) {
    int client_socket = *((int *)arg);
    struct msgvalue msg;
    while (1) {
        msg_queue_recv("msg", &msg, sizeof(msg), STM32_MSG, IPC_WAIT);
        printf("获取成功 id : %d:%d\n", msg.key, msg.status);
        if (msg.status == 1) {
            send(client_socket, "led_on\0", strlen("led_on\0"), 0);
        } else if (msg.status == 0) {
            send(client_socket, "led_off\0", strlen("led_off\0"), 0);
        }
    }
    pthread_exit(NULL);
}
union val_t {
    int b_val;
    int i_val;
    float f_val;
};

struct std_node {
    int key;              //唯一键值
    int type;             //数据点类型
    int dev_type;         //数据点属于哪个设备，根据网关支持的设备自行定义
    union val_t old_val;  //变化上报后需要更新旧值
    union val_t new_val;  //从共享内存取出最新数据，放到newval中
    int ret;              //默认为-1，采集成功后设置为0，采集失败再置-1
};

int main(int argc, char const *argv[]) {
    if (argc != 2) {
        perror("argc");
        return -1;
    }
    // 创建套接字
    int socketfd = socket(AF_INET, SOCK_STREAM, 0);
    if (socketfd < 0) {
        perror("socket creation failed");
        return -1;
    }
    printf("Socket created: %d\n", socketfd);

    // 设置网络信息
    struct sockaddr_in saddr;
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = INADDR_ANY;  //-->0.0.0.0
    saddr.sin_port = htons(atoi(argv[1]));

    // 绑定套接子
    if (bind(socketfd, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in)) < 0) {
        perror("bind error");
        return -1;
    }
    printf("Bind successful\n");

    // 监听套接字
    if (listen(socketfd, 6) < 0) {
        perror("listen error");
        return -1;
    }
    printf("Listen successful\n");
	
    // 接收客户端请求
    struct sockaddr_in caddr;
    socklen_t caddr_len = sizeof(struct sockaddr_in);
    int acceptfd;
    while (1) {
        acceptfd = accept(socketfd, (struct sockaddr *)&caddr, &caddr_len);
        if (acceptfd < 0) {
            perror("accept error");
            return -1;
        }
        //建立线程进行接收
        pthread_t tid;
        if (pthread_create(&tid, NULL, send_message, &acceptfd) != 0) {
            perror("Thread creation failed");
            exit(EXIT_FAILURE);
        }
        pthread_detach(tid);
        printf("Accept successful\n");
        printf("IP: %s \tPORT: %d\n", inet_ntoa(caddr.sin_addr), (int)ntohs(caddr.sin_port));
        char buf[128];
        char msg[1024];
        char name[50];
        // 发送和接收数据
        int key, type;
        bool b_val;
        float f_val;
        int ret;
        struct shm_param para;
        struct std_node *d;
        shm_init(&para, "shm", 4);
        d = (struct std_node *)((int *)shm_getaddr(&para) + 1);
        while ((ret = recv(acceptfd, buf, 128, 0)) > 0) {
            buf[ret] = '\0';  // 添加字符串结束符
            sscanf(buf, "{key: %d type: %d", &key, &type);
            if (type == 0) {
                if (key == 307) {
                    sscanf(buf, "{key: %d type: %d name: \"%[^\"]\", data: %d }\n", &key, &type, name, (int *)&b_val);
                    d->new_val.b_val = b_val;
                    memset(name, 0, 50);
                }
            } else if (type == 2) {
                sscanf(buf, "{key: %d type: %d name: \"%[^\"]\", data: %f }\n", &key, &type, name, &f_val);
                switch (key) {
                    case 308:
                        (d + 1)->new_val.f_val = f_val;
                        break;
                    case 309:
                        (d + 2)->new_val.f_val = f_val;
                        break;
                    case 310:
                        (d + 3)->new_val.f_val = f_val;
                        break;
                }
                memset(name, 0, 50);
            }
            memset(buf, 0, 128);
        }
        if (ret == 0) {
            close(acceptfd);
            printf("Client closed the connection\n");
        } else {
            perror("recv error");
        }
    }
    // 关闭套接字
    close(socketfd);
    return 0;
}
